﻿// <copyright file="DeliverController.cs" company="PlaceholderCompany">
// Copyright (c) PlaceholderCompany. All rights reserved.
// </copyright>

namespace MesAPI.Controllers.Maintenance
{
    using System.Text;
    using MesAPI.Extensions.AuthContext;
    using Microsoft.AspNetCore.Authorization;
    using Microsoft.AspNetCore.Mvc;
    using PublicData;
    using PublicModelsAndEntities.Models.MaintenanceRecord;
    using XinjeMesProgram.Entities;
    using XinjeMesProgram.Entities.BookInfo;

    /// <summary>
    /// 发货界面控制器.
    /// </summary>
    [ApiController]
    [Authorize]
    public class DeliverController : ControllerBase
    {
#pragma warning disable SA1000 // Keywords should be spaced correctly
#pragma warning disable CS8602 // 解引用可能出现空引用。
        private ResponseModel response = new();

        /// <summary>
        /// 发货数据获取 .
        /// </summary>
        /// <param name="pageSize">每页记录条数 .</param>
        /// <param name="currentPage">当前页码 .</param>
        /// <param name="weixiuDate">包装时间 .</param>
        /// <param name="oneDimensionalCode">产品序列号（一维码）.</param>
        /// <param name="PackageDate">包装.</param>
        /// <param name="shippingNumber">发货编号 .</param>
        /// <param name="product_category">产品状态 .</param>
        /// <returns> .</returns>
        [Route("api/v1/shipmentDataE/shipmentData")]
        [HttpGet]
        public ResponseModel ShipmentData(int pageSize, int currentPage, string? weixiuDate, string? oneDimensionalCode, string? PackageDate, string? shippingNumber, string? product_category)
        {
            using var context = new FactoryMesContext();
            string state = string.Empty;

            if (product_category != null && product_category.Equals("维修完成"))
            {
                state = "6";
            }
            else if (product_category != null && product_category.Equals("已包装"))
            {
                state = "7";
            }
            else if (product_category != null && product_category.Equals("已发货"))
            {
                state = "8";
            }
            else
            {
                state = "0";
            }

            var query = from sr in context.MainsortRecord
                        join rp in context.RepairProduct on sr.ID equals rp.ProductId
                        join d in context.Deliver on sr.ID equals d.ProductId
                        where (state == "0" ? new[] { "6", "7", "8" } : new[] { state }).Contains(sr.State)
                        select new DeliverDataModel
                        {
                            id = d.ProductId,
                            shippingNumber = rp.ShippingNumber, // 发货编号
                            one_dimensional_code = sr.One_Dimensional_Code, // 产品序列号（一维码）
                            product_model = sr.Product_Model, // 产品型号
                            product_Name = sr.Product_Name, // 产品名称
                            product_classification = sr.Product_Classification, // 产品分类
                            product_category = sr.Product_Category, // 产品组类别
                            state = sr.State == "6" ? "维修完成" : (sr.State == "7" ? "已包装" : "已发货"), // 状态
                            name = sr.Name, // 客户名称
                            abutment = rp.SkillManager, // 技术对接
                            consignee = sr.Consignee, // 收货人
                            contact_information = sr.Contact_Information, // 客户联系方式
                            repairTime = rp.RepairTime, // 维修完成时间

                            // mergeStatusdate = d.MergeStatusDate == null ? "" : d.MergeStatusDate.Value.ToString("") ?? "", // 合并时间
                            mergeStatusdate = d.MergeStatusDate, // 合并时间
                            shipping_address = sr.Shipping_Address, // 收货地址
                            delivery_numberOut = d.NumberOut, // 发货快递单号
                            delivery_nameOut = d.NameOut, // 发货快递名称
                            assignPersonnel = sr.AssignPersonnelUserId == null ? string.Empty : context.MesUserRole.FirstOrDefault(x => x.ID == sr.AssignPersonnelUserId).UserName, // 分配人员
                            registration_a = "登记", // 不需要保存
                            registration_b = "发货", // 不需要保存
                            counta = d.Counta == null ? 0 : d.Counta, // 合并参数
                            datex = d.DeliveryTime == null ? string.Empty : d.DeliveryTime.Value.ToString(string.Empty) ?? string.Empty, // 发货时间
                            choice = 0, // 勾选框
                            customerLevel = sr.CustomerLevel, // 客户等级
                            PackagingTime = d.PackagingTime,  // 包装时间
                        };

            // query = query.OrderBy(sr => sr.Contact_information);
            // 根据一维码进行查询，判断一维码输入框是否为空或Null，且发货单号框要为null或为空字符串
            if (!string.IsNullOrEmpty(oneDimensionalCode) && string.IsNullOrEmpty(shippingNumber))
            {
                query = query.Where(x => x.one_dimensional_code.Contains(oneDimensionalCode));
            }

            // 根据发货编号进行查询，判断快递编号输入框是否为空或Null，且一维码框要为null或为空字符串
            if (!string.IsNullOrEmpty(shippingNumber) && string.IsNullOrEmpty(oneDimensionalCode))
            {
                query = query.Where(x => x.shippingNumber.Contains(shippingNumber));
            }

            if (!string.IsNullOrEmpty(weixiuDate))
            {
                query = query.Where(x => x.repairTime.Contains(weixiuDate));
            }

            if (!string.IsNullOrEmpty(PackageDate))
            {
                query = query.Where(x => x.PackagingTime.Contains(PackageDate));
            }

            List<DeliverDataModel> list = query.ToList();

            // list.Sort((a, b) => a.Contact_information == b.Contact_information ? b.mergeStatusdate.CompareTo(a.mergeStatusdate) : b.Contact_information.CompareTo(a.Contact_information));
            // 排序：发货时间、收货人联系方式、合并时间
            // list = list.OrderBy(x => x.datex).ThenBy(x => x.Contact_information).ThenBy(x => x.mergeStatusdate).ToList();
            // list = list.OrderByDescending(x => x.datex).ThenBy(x => x.Contact_information).ThenBy(x => x.mergeStatusdate).ToList();
            list = list.OrderBy(x => x.name).ToList();
            list = list.OrderBy(x => x.customerLevel).ToList();
            list = list.OrderBy(x => x.state).ToList();

            // list = list.OrderBy(x => x.PackagingTime).ToList();
            // list = list.OrderBy(x => x.Contact_information).ToList();
            // list = list.OrderByDescending(x => x.name).ToList();
            // list = list.OrderByDescending(x => x.mergeStatusdate).ToList();
            this.response.SetData(list.ListPaged(currentPage, pageSize), list.Count);

            // 暂时不启用
            if (false)
            {
                StringBuilder csvContent = new();
                csvContent.AppendLine("发货编号,客户名称,客户联系方式,客户收货地址,产品编码,产品规格型号,产品组类别,产品分类,产品名称,状态,包装时间,维修完成时间,发货日期,发货快递名称,发货快递号,工程师名称");  // 发货数据导出表 表头
                foreach (var book in query)
                {
                    string csvLine = string.Format(
                        "{0},{1},{2},{3},{4},{5},{6},{7},{8},{9},{10},{11},{12},{13},{14},{15}",
                        book.shippingNumber,            // 发货编号
                        book.name,                      // 客户名称
                        book.contact_information,       // 客户联系方式
                        book.shipping_address,          // 客户收货地址
                        book.one_dimensional_code,      // 产品编码
                        book.product_model,             // 产品规格型号
                        book.product_category,          // 产品组类别
                        book.product_classification,    // 产品分类
                        book.product_Name,              // 产品名称
                        book.state,                     // 状态
                        book.PackagingTime,             // 包装时间
                        book.repairTime,                // 维修完成时间
                        book.datex,                     // 发货日期
                        book.delivery_nameOut,          // 发货快递名称
                        book.delivery_numberOut,        // 发货快递号
                        book.assignPersonnel); ///////////// 工程师名称

                    csvContent.AppendLine(csvLine);
                }

                string exportFolderPath = "C:\\WebSite\\XinjeMesApi\\wwwroot\\xlsx";
                string ambin = "发货数据表" + DateTime.Now.ToString("mm-ss") + "(含维修记录).csv";
                string csvFilePath = Path.Combine(exportFolderPath, ambin);
                System.IO.File.WriteAllText(csvFilePath, csvContent.ToString(), Encoding.UTF8); // 创建文件到  C:\\WebSite\\XinjeMesApi\\wwwroot\\xlsx（服务器）
                string downloadLink = "/xlsx/" + ambin;  // 下载链接
                this.response.SetSuccess(downloadLink);
            }

            return this.response;
        }

        /// <summary>
        /// 发货登记保存 .
        /// </summary>
        /// <param name="datas">datas .</param>
        /// <returns> .</returns>
        [Route("api/v1/unshippedE/unshipped")]
        [HttpPost]
        public ResponseModel Unshipped(List<DeliverRegisterModel>? datas)
        {
            using var context = new FactoryMesContext();
            foreach (DeliverRegisterModel data in datas)
            {
                var model = context.MainsortRecord.FirstOrDefault(x => x.ID == data.id);
                var deliver = context.Deliver.Where(x => x.ProductId == data.id).ToList();
                if (deliver.Count <= 0)
                {
                    this.response.SetError();
                    return this.response;
                }

                if ((model != null && (model.State.Equals("6") || model.State.Equals("7"))) && (deliver[0].State.Equals("0") || deliver[0].State.Equals("1")) && !string.IsNullOrEmpty(data.id))
                {
                    deliver[0].NumberOut = data.delivery_numberOut; // 发货快递单号
                    deliver[0].NameOut = data.delivery_nameOut; // 发货快递名称
                    model.Shipping_Address = data.shipping_address; // 发货地址
                    deliver[0].Counta = data.counta; // 合并参数
                    model.Contact_Information = data.contact_information; // 电话号码

                    // deliver[0].MergeStatusDate = (data.mergeStatusdatec == null || data.mergeStatusdatec == "") ? DateTime.Parse("1999-01-01 00:00:00.000") : DateTime.Parse(data.mergeStatusdatec); // 合并时间
                    deliver[0].MergeStatusDate = data.mergeStatusdate; // 合并时间
                    context.SaveChanges();
                }
                else
                {
                    this.response.SetFailed();
                    break;
                }
            }

            return this.response;
        }

        /// <summary>
        /// 提交发货 .
        /// </summary>
        /// <param name="datas">datas .</param>
        /// <returns> .</returns>
        [Route("api/v1/shippedE/shipped")]
        [HttpPost]
        public ResponseModel Shipped(List<DeliverDeliverModel> datas)
        {
            using var context = new FactoryMesContext();
            foreach (DeliverDeliverModel data in datas)
            {
                var sort = context.MainsortRecord.FirstOrDefault(x => x.ID == data.id);
                var deliver = context.Deliver.FirstOrDefault(x => x.ProductId == data.id);
                if (!string.IsNullOrEmpty(sort.ID) && sort.State.Equals("6") && !string.IsNullOrEmpty(data.id) && data.state == "已包装")
                {
                    deliver.State = "1";
                    sort.State = "7";
                    deliver.Counta = data.counta; // 合并参数
                    deliver.PackagingTime = DateTime.Now.ToString("yyyy/MM/dd"); // 包装时间

                    context.SaveChanges();
                }
                else if (!string.IsNullOrEmpty(sort.ID) && sort.State.Equals("7") && !string.IsNullOrEmpty(data.id) && data.state == "已发货")
                {
                    deliver.State = "2";
                    sort.State = "8";

                    // deliver.ShipmentSequence = DateTime.Now.ToString("yyMMddHHmmssfff"); // 发货单号
                    deliver.DeliveryTime = DateTime.Now; // 发货时间
                    context.SaveChanges();
                }
                else
                {
                    this.response.SetFailed();
                    break;
                }
            }

            return this.response;
        }

        /// <summary>
        /// 包装超期统计 .
        /// </summary>
        /// <returns> .</returns>
        [Route("/api/v1/reForms/DeliverConerprompt")]
        [HttpGet]
        public ResponseModel DeliverConerprompt()
        {
            AuthContextUser currentUser = AuthContextService.CurrentUser;
            using var context = new FactoryMesContext();
            int[] str = { 0, 0 };

            // 获取假期列表
            List<DateTime> holidays = this.GetHolidays();

            var query = from sr in context.MainsortRecord
                        join rp in context.RepairProduct
                          on sr.ID equals rp.ProductId into rpGroup
                        from rp in rpGroup.DefaultIfEmpty()
                        join d in context.Deliver
                          on sr.ID equals d.ProductId into dGroup
                        from d in dGroup.DefaultIfEmpty()
                        where d.State == "0" && sr.State == "6"
                        select new DeliverRepair
                        {
                            packagingTime = DateTime.Now,
                            repairCompletedTime = rp.RepairCompletedTime,
                        };

            List<DeliverRepair> result = query.ToList();
            str[1] = result.Where(x => x.repairCompletedTime != null && (x.packagingTime - x.repairCompletedTime).Value.Days <= 2).Count();
            str[0] = result.Where(x => x.repairCompletedTime != null && (x.packagingTime - x.repairCompletedTime).Value.Days > 3).Count();

            result = result.Where(x => x.repairCompletedTime != null && (x.packagingTime - x.repairCompletedTime).Value.Days == 3).ToList();
            int r = 0;
            foreach (var item in result)
            {
                for (DateTime date = (DateTime)item.repairCompletedTime; date <= item.packagingTime; date = date.AddDays(1))
                {
                    if (date.DayOfWeek == DayOfWeek.Sunday)
                    {
                        str[1] += 1;
                        r = 1;
                    }
                }

                if (r == 0)
                {
                    str[0] += 1;
                }
            }

            this.response.SetData(str);
            return this.response;
        }

        // 判断是否为假期
        private bool IsHoliday(DateTime date)
        {
            List<DateTime> holidays = this.GetHolidays();
            return holidays.Contains(date.Date);
        }

        // 获取假期列表
        private List<DateTime> GetHolidays()
        {
            List<DateTime> holidays = new();

            // TODO: 根据实际情况获取假期列表
            return holidays;
        }

        /*public ResponseModel DeliverConerprompt()
        {
            AuthContextUser currentUser = AuthContextService.CurrentUser;
            using var context = new FactoryMesContext();
            int[] str = { 0, 0 };

            var query = from sr in context.MainsortRecord
                        join rp in context.RepairProduct
                          on sr.ID equals rp.ProductId into rpGroup
                        from rp in rpGroup.DefaultIfEmpty()
                        join d in context.Deliver
                          on sr.ID equals d.ProductId into dGroup
                        from d in dGroup.DefaultIfEmpty()
                        where d.State == "0" && sr.State == "6"
                        select new DeliverRepair
                        {
                            packagingTime = DateTime.Now,
                            repairCompletedTime = rp.RepairCompletedTime,
                        };

            List<DeliverRepair> result = query.ToList();
            str[0] = result.Where(x => x.repairCompletedTime != null && (x.packagingTime - x.repairCompletedTime).Value.Days > 2).Count();
            str[1] = result.Where(x => x.repairCompletedTime != null && (x.packagingTime - x.repairCompletedTime).Value.Days < 2).Count();
            this.response.SetData(str);
            return this.response;*/
    }
}